package com.chansos.dubbogo.hessian_generator;

import com.chansos.dubbogo.common.Constant;

import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class Generator {
    private static String escape(String str) {
        return str.trim().replaceAll("\\.", "\\\\.").replaceAll("\\(", "\\\\(").replaceAll("\\)", "\\\\)").replaceAll("\\{", "\\\\{").replaceAll("}", "\\}");
    }

    public static void generate(FileInfo fileInfo) {
        if (fileInfo == null) {
            return;
        }
        appendHessianImport(fileInfo);
        appendInitFunction(fileInfo);
        appendPOJOImplement(fileInfo);
    }

    private static void appendHessianImport(FileInfo fileInfo) {
        if (fileInfo.isHasHessianImport()) {
            return;
        }
        int offset = fileInfo.getAppendOffset();
        int sliceIndex = fileInfo.getPackageEndIndex() + offset;
        fileInfo.getStringBuffer().insert(sliceIndex, Constant.hessianImport);
        fileInfo.setAppendOffset(offset + Constant.hessianImport.length());
    }

    private static void appendInitFunction(FileInfo fileInfo) {
        int offset = fileInfo.getAppendOffset();
        StringBuilder stringBuffer = fileInfo.getStringBuffer();
        String registerPOJOStatement;
        if (fileInfo.isHasInitFunction()) {
            int sliceIndex = fileInfo.getInitFuncStatementStartIndex() + offset;
            String initFunctionStatement = stringBuffer.substring(sliceIndex, fileInfo.getInitFuncEndIndex() + offset - 1);
            registerPOJOStatement = genRegisterPOJOStatements(fileInfo, initFunctionStatement);
            stringBuffer.insert(sliceIndex, registerPOJOStatement);
        } else {
            registerPOJOStatement = genRegisterPOJOStatements(fileInfo, null);
            stringBuffer.append(Constant.genInitFunctionStatement(registerPOJOStatement));
        }
        fileInfo.setAppendOffset(offset + registerPOJOStatement.length());
    }

    private static String genRegisterPOJOStatements(FileInfo fileInfo, String initFunctionStatement) {
        StringBuilder stringBuilder = new StringBuilder();
        Matcher matcher;
        for (String structName : fileInfo.getGoStructMap().keySet()) {
            String statement = Constant.genRegisterPOJOStatement(structName);
            if (initFunctionStatement != null) { // 检测是否已存在注册方法体
                matcher = Pattern.compile(escape(statement)).matcher(initFunctionStatement);
                if (matcher.find()) {
                    int i = matcher.start();
                    int n = initFunctionStatement.lastIndexOf(Constant.newLine, i);
                    String checkStatement = initFunctionStatement.substring(initFunctionStatement.lastIndexOf(Constant.newLine, n) + 1, i);
                    matcher = Pattern.compile(Constant.LineCommentRegexp).matcher(checkStatement);
                    if (!matcher.find()) {  // 是否被行注释
                        continue;
                    }
                }
            }
            stringBuilder.append(Constant.newLine).append(statement).append(Constant.newLine);
        }
        return stringBuilder.toString();
    }

    private static void appendPOJOImplement(FileInfo fileInfo) {
        StringBuilder stringBuffer = fileInfo.getStringBuffer();
        fileInfo.getGoStructMap().forEach((k, v) -> {
            if (!v.isHasHessianPOJOImplements()) { // 追加 hessian.POJO实现
                String statement = Constant.genHessianPOJOImplementFunction(k);
                stringBuffer.append(statement);
            }
        });
    }
}
